package nl.unimaas.micc.eventSnookerTest.math;

public class BairstowSolver2
{
        /*public static void main(String arg[])
        {
                //double a[]={1.0,-15.0,85.0,-225.0,274.0,-120.0};
                
                double[] a = {0.05752486561365758, 0.05564212195159408, -0.2623001777453935, -0.13404557207748724, 0.3300567297419647};

                BairstowSolver2 bs=new BairstowSolver2(a);
				bs.solve();
        }*/
        
        public boolean foundReal() {
        	return foundReal;
        }

		public BairstowSolver2(double[] coefficients)
		{
			this.p = coefficients;
			this.n = coefficients.length-1;
		}

        private void answer(double a,double b,double c)
        {
                double Re1,Re2,Im1,Im2,D;     
                D=b*b-4*a*c;     
                if(D>0) 
                {
                        Re1=(-b+Math.sqrt(D))/(2*a);
                        Re2=(-b-Math.sqrt(D))/(2*a);
                        Im1=0;
                        Im2=0;
                }
                else if(D==0)
                {
                        Re1=-b/(2*a);
                        Im1=0;
                        Re2=Im2=0;
                }
                else
                {
                        Re1=-b/(2*a);
                        Re2=Re1;
                        Im1=Math.sqrt(-D)/(2*a);
                        Im2=-Im1;
                }
                if ((Re1 > 0 && Im1 == 0.0) || (Re2 > 0 && Im2 == 0.0))
                {
                	foundReal = true;
                	if(Im1==0.0)
                	{
                		regMin(Re1);
                	}
                	if(Im2==0.0)
                	{
                		regMin(Re2);
                	}
                }
                if(D==0)
                {
//                        System.out.println( Re1 + "+" + "i" + Im1);
                }
                else
                {
//                        System.out.println( Re1 + "+" + "i" + Im1);
//                        System.out.println( Re2 + "+" + "i" + Im2);
                }
        }

        private void regMin(double re)
		{
        	if(re<min && re>0)
        	{
        		min=re;
        	}
		}

		public void solve()
        {
			System.out.println("BS2 ...");
                int i,max;
                double det,db,dc,q[]=new double[n+1],u[]=new double[n+1],w[]=new double[n+1];
                double xxx,b,c;

                max=0;
                xxx=1.0;
        
                while (true)
                {
                        b=c=1.0;

                        do 
                        {
                                max++;

                                for(i=0;i<=n;i++) 
                                {
                                        if(i==0) q[i]=p[i];
                                        else if(i==1) q[i]=p[i]-b*q[i-1];
                                        else q[i]=p[i]-b*q[i-1]-c*q[i-2];
                                }
                                for(i=0;i<=n;i++) 
                                {
                                        if(i==0) u[i]=0.0;
                                        else if(i==1) u[i]=-q[i-1]-b*u[i-1];
                                        else u[i]=-q[i-1]-b*u[i-1]-c*u[i-2];
                                }
                                for(i=0;i<=n;i++) 
                                {
                                        if(i==0) w[i]=0.0;
                                        else if(i==1) w[i]=-b*w[i-1];
                                        else w[i]=-q[i-2]-b*w[i-1]-c*w[i-2];
                                }

                                det=u[n-1]*w[n]-w[n-1]*(u[n]+q[n-1]);
                                db=1.0/det*(q[n]*w[n-1]-q[n-1]*w[n]);
                                dc=1.0/det*(-q[n]*u[n-1]+q[n-1]*(u[n]+q[n-1]));

                                b+=db;
                                c+=dc;
                        }while ( db*db+dc*dc > EPSILON * EPSILON );

                        for(i=0;i<=n-2;i++) p[i]=q[i];

                        if(n>=3) 
                        {
                                answer(xxx,b,c);
                                n-=2;
                        }
                        else if(n==2) 
                        {
                                answer(p[0],p[1],p[2]);
                                break;
                        }
                        else if(n==1) 
                        {
                        		System.out.println(-p[1]/p[0]+ "i" + "0");
                                break;
                        }
                }
                System.out.println("... BS2");
        }
		
		public double getMinReal()
		{
			return min;
		}

		private double[] p;
		private int n;
        
        private boolean foundReal = false;
		private double min = Double.MAX_VALUE;
		
		private static final double EPSILON=1.0e-5;


}